/**
  ******************************************************************************
  * @file    sym32l010_hal_lptim.h
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   Header file of LPTIM HAL module.
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SYM32L010_HAL_LPTIM_H
#define __SYM32L010_HAL_LPTIM_H

#ifdef __cplusplus
extern "C" {
#endif


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "sym32l010_hal_def.h"


/******************************************************************************/
/* Global type definitions                                                    */
/******************************************************************************/
/* LPTIM 基本模式 -------------------------------------------------------------*/
typedef enum
{
    LPTIM_WORKMODE_TIMER        = 0x0UL,                              // 基本定时器模式
    LPTIM_WORKMODE_COUNTER_SYNC = LPTIM_CFGR_COUNTMD_Msk,             // 同步计数器模式
    LPTIM_WORKMODE_COUNTER_ASYN = LPTIM_CFGR_CKSEL_Msk,               // 异步计数器模式
    LPTIM_WORKMODE_ENCODER      = LPTIM_CFGR_ENC_Msk                  // 编码器模式
} LPTIM_WorkModeTypeDef;

/* LPTIM ICLK来源 ------------------------------------------------------------*/
typedef enum
{
    LPTIM_ICLKSRC_PCLK         = (0x0UL << LPTIM_CFGR_ICLKSRC_Pos),   // PCLK
    LPTIM_ICLKSRC_LSE          = (0x2UL << LPTIM_CFGR_ICLKSRC_Pos),   // LSE
    LPTIM_ICLKSRC_LSI          = (0x3UL << LPTIM_CFGR_ICLKSRC_Pos)    // LSI
} LPTIM_ICLKSourceTypeDef;

/* LPTIM ARR/CMP寄存器更新 ----------------------------------------------------*/
typedef enum
{
    LPTIM_PRELOAD_IMMEDIATE    = (0x0UL << LPTIM_CFGR_PRELOAD_Pos),   // 立即更新
    LPTIM_PRELOAD_ENDOFPERIOD  = (0x1UL << LPTIM_CFGR_PRELOAD_Pos)    // 周期结束更新
} LPTIM_PreLoadTypeDef;

/* LPTIM 时钟分频 -------------------------------------------------------------*/
typedef enum
{
    LPTIM_PRS_1                = (0x0UL << LPTIM_CFGR_PRS_Pos),       // 1 分频
    LPTIM_PRS_2                = (0x1UL << LPTIM_CFGR_PRS_Pos),       // 2 分频
    LPTIM_PRS_4                = (0x2UL << LPTIM_CFGR_PRS_Pos),       // 4 分频
    LPTIM_PRS_8                = (0x3UL << LPTIM_CFGR_PRS_Pos),       // 8 分频
    LPTIM_PRS_16               = (0x4UL << LPTIM_CFGR_PRS_Pos),       // 16 分频
    LPTIM_PRS_32               = (0x5UL << LPTIM_CFGR_PRS_Pos),       // 32 分频
    LPTIM_PRS_64               = (0x6UL << LPTIM_CFGR_PRS_Pos),       // 64 分频
    LPTIM_PRS_128              = (0x7UL << LPTIM_CFGR_PRS_Pos)        // 128 分频
} LPTIM_PrescalerTypeDef;

/* LPTIM 运行控制 -------------------------------------------------------------*/
typedef enum
{
    LPTIM_STARTMODE_CNT        = (0x1UL << LPTIM_CR_CNTSTART_Pos),    // 连续运行
    LPTIM_STARTMODE_SNG        = (0x1UL << LPTIM_CR_SNGSTART_Pos)     // 单脉冲运行
} LPTIM_StartModeTypeDef;

/* LPTIM 触发源 --------------------------------------------------------------*/
typedef enum
{
    LPTIM_TRS_ETR              = (0x0UL << LPTIM_CFGR_TRIGSEL_Pos),   // LPTIM_ETR管脚输入的信号
    LPTIM_TRS_RTC_ALARMA       = (0x1UL << LPTIM_CFGR_TRIGSEL_Pos),   // RTC的AlarmA匹配信号
    LPTIM_TRS_RTC_ALARMB       = (0x2UL << LPTIM_CFGR_TRIGSEL_Pos),   // RTC的AlarmB匹配信号
    LPTIM_TRS_RTC_AWT_OV       = (0x3UL << LPTIM_CFGR_TRIGSEL_Pos),   // RTC的唤醒定时器唤醒信号
    LPTIM_TRS_RTC_TAMP_EVENT   = (0x4UL << LPTIM_CFGR_TRIGSEL_Pos),   // RTC的时间戳事件信号
    LPTIM_TRS_RTC_1Hz          = (0x5UL << LPTIM_CFGR_TRIGSEL_Pos),   // RTC输出的1Hz信号
    LPTIM_TRS_VC1_OUT          = (0x6UL << LPTIM_CFGR_TRIGSEL_Pos),   // VC1输出的信号
    LPTIM_TRS_VC2_OUT          = (0x7UL << LPTIM_CFGR_TRIGSEL_Pos)    // VC2输出的信号
} LPTIM_TriggerSourceTypeDef;

/* LPTIM 使能与极性 -----------------------------------------------------------*/
typedef enum
{
    LPTIM_TRIG_SOFT            = (0x0UL << LPTIM_CFGR_TRIGEN_Pos),    // 软件触发，由软件写寄存器启动计数器
    LPTIM_TRIG_HARD_RISING     = (0x1UL << LPTIM_CFGR_TRIGEN_Pos),    // 硬件触发，在触发信号上升沿启动计数器
    LPTIM_TRIG_HARD_FALLING    = (0x2UL << LPTIM_CFGR_TRIGEN_Pos),    // 硬件触发，在触发信号下降沿启动计数器
    LPTIM_TRIG_HARD_BOTH       = (0x3UL << LPTIM_CFGR_TRIGEN_Pos)     // 硬件触发，在触发信号上升沿或下降沿启动计数器
} LPTIM_TriggerModeTypeDef;

/* LPTIM 触发信号滤波 ---------------------------------------------------------*/
typedef enum
{
    LPTIM_TRIGFLT_NONE         = (0x0UL << LPTIM_CFGR_TRIGFLT_Pos),   // 不滤波
    LPTIM_TRIGFLT_ICLK2        = (0x1UL << LPTIM_CFGR_TRIGFLT_Pos),   // 2个ICLK时钟周期
    LPTIM_TRIGFLT_ICLK4        = (0x2UL << LPTIM_CFGR_TRIGFLT_Pos),   // 4个ICLK时钟周期
    LPTIM_TRIGFLT_ICLK8        = (0x3UL << LPTIM_CFGR_TRIGFLT_Pos)    // 8个ICLK时钟周期
} LPTIM_TriggerFilterTypeDef;

/* LPTIM 触发超时控制 ---------------------------------------------------------*/
typedef enum
{
    LPTIM_TRIGTIMEOUT_ENABLE   = (0x0UL << LPTIM_CFGR_TIMOUT_Pos),    // 正在计数时发生的触发事件被忽略
    LPTIM_TRIGTIMEOUT_DISABLE  = (0x1UL << LPTIM_CFGR_TIMOUT_Pos)     // 正在计数时发生的触发事件将计数值清零并重新开始计数
} LPTIM_TriggerTimeOutEnTypeDef;

/* LPTIM TCLK时钟来源 ---------------------------------------------------------*/
typedef enum
{
    LPTIM_CKSEL_MCLK           = (0x0UL << LPTIM_CFGR_CKSEL_Pos),     // 计数时钟来自MCLK
    LPTIM_CKSEL_CH1FPD         = (0x1UL << LPTIM_CFGR_CKSEL_Pos)      // 计数时钟来自CH1FPD
} LPTIM_ClockSelectTypeDef;

/* LPTIM 输出波形极性 ---------------------------------------------------------*/
typedef enum
{
    LPTIM_WAVEPOL_POSITIVE     = (0x0UL << LPTIM_CFGR_WAVPOL_Pos),    // PWM正向输出，CNT > CMP 输出高电平
    LPTIM_WAVEPOL_NEGATIVE     = (0x1UL << LPTIM_CFGR_WAVPOL_Pos)     // PWM反向输出，CNT <= CMP 输出高电平
} LPTIM_WavePolarityTypeDef;

/* LPTIM 输出波形控制 ---------------------------------------------------------*/
typedef enum
{
    LTPTIM_WAVE_DISABLE        = (0x0UL << LPTIM_CFGR_WAVE_Pos),      // 单次启动对应单脉冲波形，连续启动对应PWM波形
    LTPTIM_WAVE_ENABLE         = (0x1UL << LPTIM_CFGR_WAVE_Pos)       // 单次置位波形
} LPTIM_WaveTypeDef;

/* LPTIM 编码器工作模式 -------------------------------------------------------*/
typedef enum
{
    LPTIM_ENCMODE_CH1          = (0x0UL << LPTIM_CFGR_ENCMD_CKPOL_Pos), // 编码计数模式1，CH1信号变化沿计数
    LPTIM_ENCMODE_CH2          = (0x1UL << LPTIM_CFGR_ENCMD_CKPOL_Pos), // 编码计数模式2，CH2信号变化沿计数
    LPTIM_ENCMODE_CH1CH2       = (0x2UL << LPTIM_CFGR_ENCMD_CKPOL_Pos)  // 编码计数模式3，CH1/CH2信号变化沿计数
} LPTIM_EncModeTypeDef;

/* LPTIM CH1CH2滤波 ----------------------------------------------------------*/
typedef enum
{
    LPTIM_CHxFLT_NONE          = (0x0UL << LPTIM_CFGR_CHFLT_Pos),     // 无滤波功能
    LPTIM_CHxFLT_ICLK2         = (0x1UL << LPTIM_CFGR_CHFLT_Pos),     // 2个ICLK时钟周期
    LPTIM_CHxFLT_ICLK4         = (0x2UL << LPTIM_CFGR_CHFLT_Pos),     // 4个ICLK时钟周期
    LPTIM_CHxFLT_ICLK8         = (0x3UL << LPTIM_CFGR_CHFLT_Pos)      // 8个ICLK时钟周期
} LPTIM_CHxFilterTypeDef;

/* LPTIM CH1计数边沿 ----------------------------------------------------------*/
typedef enum
{
    LPTIM_CKPOL_RISE           = (0x0UL << LPTIM_CFGR_ENCMD_CKPOL_Pos), // CH1信号上升沿计数器递增
    LPTIM_CKPOL_FALL           = (0x1UL << LPTIM_CFGR_ENCMD_CKPOL_Pos), // CH1信号下降沿计数器递增
    LPTIM_CKPOL_BOTH           = (0x2UL << LPTIM_CFGR_ENCMD_CKPOL_Pos)  // CH1信号上升沿或下降沿时计数器递增
} LPTIM_Ch1EdgeTypeDef;

/* LPTIM 初始化 --------------------------------------------------------------*/
typedef struct
{
    uint16_t                   Reload;                                // LPTIM 重装载值  (0 ... 0xFFF)
    LPTIM_WorkModeTypeDef      WorkMode;                              // LPTIM 基本模式
    LPTIM_ICLKSourceTypeDef    ICLKSource;                            // LPTIM ICLK来源
    LPTIM_PreLoadTypeDef       PreLoad;                               // LPTIM ARR/CMP寄存器更新
    LPTIM_PrescalerTypeDef     Prescaler;                             // LPTIM 时钟分频
    LPTIM_StartModeTypeDef     StartMode;                             // LPTIM 运行控制
    LPTIM_TriggerModeTypeDef   TriggerMode;                           // LPTIM 触发使能与极性
} LPTIM_InitTypeDef;

/* LPTIM 触发配置初始化 -------------------------------------------------------*/
typedef struct
{
    LPTIM_TriggerSourceTypeDef    TriggerSource;                      // LPTIM 触发源
    LPTIM_TriggerFilterTypeDef    TriggerFilter;                      // LPTIM 触发信号滤波
    LPTIM_TriggerTimeOutEnTypeDef TriggerTimeOutEn;                   // LPTIM 触发超时控制
} LPTIM_TrigConfigTypeDef;

/* LPTIM 编码器初始化 ---------------------------------------------------------*/
typedef struct
{
    LPTIM_EncModeTypeDef      EncMode;                                // LPTIM 编码器工作模式
    LPTIM_CHxFilterTypeDef    CHxFilter;                              // LPTIM CH1CH2滤波
} LPTIM_EncConfigTypeDef;


/******************************************************************************/
/* Global pre-processor symbols/macros ('#define')                            */
/******************************************************************************/
/* LPTIM 中断触发源 -----------------------------------------------------------*/
#define LPTIM_IT_SOURCE_CMPM             (LPTIM_IER_CMPM_Msk)
#define LPTIM_IT_SOURCE_ARRM             (LPTIM_IER_ARRM_Msk)
#define LPTIM_IT_SOURCE_EXTTRIG          (LPTIM_IER_EXTTRIG_Msk)
#define LPTIM_IT_SOURCE_CMPOK            (LPTIM_IER_CMPOK_Msk)
#define LPTIM_IT_SOURCE_ARROK            (LPTIM_IER_ARROK_Msk)
#define LPTIM_IT_SOURCE_UP               (LPTIM_IER_UP_Msk)
#define LPTIM_IT_SOURCE_DOWN             (LPTIM_IER_DOWN_Msk)

/* LPTIM 状态标志 -------------------------------------------------------------*/
#define LPTIM_IT_FLAG_CMPM               (LPTIM_ISR_CMPM_Msk)
#define LPTIM_IT_FLAG_ARRM               (LPTIM_ISR_ARRM_Msk)
#define LPTIM_IT_FLAG_EXTTRIG            (LPTIM_ISR_EXTTRIG_Msk)
#define LPTIM_IT_FLAG_CMPOK              (LPTIM_ISR_CMPOK_Msk)
#define LPTIM_IT_FLAG_ARROK              (LPTIM_ISR_ARROK_Msk)
#define LPTIM_IT_FLAG_UP                 (LPTIM_ISR_UP_Msk)
#define LPTIM_IT_FLAG_DOWN               (LPTIM_ISR_DOWN_Msk)
#define LPTIM_IT_FLAG_DIR                (LPTIM_ISR_DIR_Msk)

/* LPTIM 编码器计数方向 -------------------------------------------------------*/
#define LPTIM_ENCODER_STOP_DOWN          (0x0UL << LPTIM_ISR_DIR_Pos)
#define LPTIM_ENCODER_STOP_UP            (0x1UL << LPTIM_ISR_DIR_Pos)
#define LPTIM_ENCODER_RUN_DOWN           (0x2UL << LPTIM_ISR_DIR_Pos)
#define LPTIM_ENCODER_RUN_UP             (0x3UL << LPTIM_ISR_DIR_Pos)


/******************************************************************************/
/* Global macro function                                                      */
/******************************************************************************/
/**
  * @brief  获取 LPTIM中断触发源
  * @param  ITSOURCE: LPTIM中断触发源
  *                   @arg LPTIM_IT_SOURCE_CMPM
  *                   @arg LPTIM_IT_SOURCE_ARRM
  *                   @arg LPTIM_IT_SOURCE_EXTTRIG
  *                   @arg LPTIM_IT_SOURCE_CMPOK
  *                   @arg LPTIM_IT_SOURCE_ARROK
  *                   @arg LPTIM_IT_SOURCE_UP
  *                   @arg LPTIM_IT_SOURCE_DOWN
  * @retval
  */
#define HAL_LPTIM_GET_IT_SOURCE(ITSOURCE)  (SYM_LPTIM->IER & (ITSOURCE))

/**
  * @brief  使能 LPTIM中断触发源
  * @param  ITSOURCE: LPTIM中断触发源
  *                   @arg LPTIM_IT_SOURCE_CMPM
  *                   @arg LPTIM_IT_SOURCE_ARRM
  *                   @arg LPTIM_IT_SOURCE_EXTTRIG
  *                   @arg LPTIM_IT_SOURCE_CMPOK
  *                   @arg LPTIM_IT_SOURCE_ARROK
  *                   @arg LPTIM_IT_SOURCE_UP
  *                   @arg LPTIM_IT_SOURCE_DOWN
  * @retval
  */
#define HAL_LPTIM_ENABLE_IT(ITSOURCE)      (SYM_LPTIM->IER |= (ITSOURCE))

/**
  * @brief  关闭 LPTIM中断触发源
  * @param  ITSOURCE: LPTIM中断触发源
  *                   @arg LPTIM_IT_SOURCE_CMPM
  *                   @arg LPTIM_IT_SOURCE_ARRM
  *                   @arg LPTIM_IT_SOURCE_EXTTRIG
  *                   @arg LPTIM_IT_SOURCE_CMPOK
  *                   @arg LPTIM_IT_SOURCE_ARROK
  *                   @arg LPTIM_IT_SOURCE_UP
  *                   @arg LPTIM_IT_SOURCE_DOWN
  * @retval
  */
#define HAL_LPTIM_DISABLE_IT(ITSOURCE)     (SYM_LPTIM->IER &= ~((uint32_t)(ITSOURCE)))

/**
  * @brief  获取LPTIM中断及编码器状态标志
  * @param  FLAG : LPTIM中断及编码器状态标志
  *                @arg LPTIM_IT_FLAG_CMPM
  *                @arg LPTIM_IT_FLAG_ARRM
  *                @arg LPTIM_IT_FLAG_EXTTRIG
  *                @arg LPTIM_IT_FLAG_CMPOK
  *                @arg LPTIM_IT_FLAG_ARROK
  *                @arg LPTIM_IT_FLAG_UP
  *                @arg LPTIM_IT_FLAG_DOWN
  *                @arg LPTIM_ISR_FLAF_DIR
  * @retval
  */
#define HAL_LPTIM_GET_FLAG(FLAG)           (SYM_LPTIM->ISR & (FLAG))

/**
  * @brief  清除 LPTIM中断触发标志
  * @param  FLAG : LPTIM中断触标志
  *                @arg LPTIM_IT_FLAG_CMPM
  *                @arg LPTIM_IT_FLAG_ARRM
  *                @arg LPTIM_IT_FLAG_EXTTRIG
  *                @arg LPTIM_IT_FLAG_CMPOK
  *                @arg LPTIM_IT_FLAG_ARROK
  *                @arg LPTIM_IT_FLAG_UP
  *                @arg LPTIM_IT_FLAG_DOWN
  * @retval
  */
#define HAL_LPTIM_CLR_FLAG(FLAG)           (SYM_LPTIM->ICR = ~((uint32_t)(FLAG)))

/**
  * @brief  LPTIM计数值异步复位
  * @param  None
  * @retval
  * @note   仅适用于异步计数模式
  */
#define HAL_LPTIM_RESET_ARST()             (SYM_LPTIM->CR = ~((uint32_t)(LPTIM_CR_CNTSTART_Msk)))

/**
  * @brief  LPTIM计数值同步复位
  * @param  None
  * @retval
  * @note   仅适用于定时模式、同步计数模式、编码计数模式
  */
#define HAL_LPTIM_RESET_SRST()             (SYM_LPTIM->CR = ~((uint32_t)(LPTIM_CR_SNGSTART_Msk)))


/******************************************************************************/
/* Exported variables ('extern', definition in C source)                      */
/******************************************************************************/


/******************************************************************************/
/* Global function prototypes ('extern', definition in C source)              */
/******************************************************************************/
void     HAL_LPTIM_Init(LPTIM_InitTypeDef *InitStruct);
void     HAL_LPTIM_DeInit(void);
void     HAL_LPTIM_Start(void);
void     HAL_LPTIM_Stop(void);
void     HAL_LPTIM_DelayPclk(uint16_t PclkCnt);
uint16_t HAL_LPTIM_IsRunning(void);
uint16_t HAL_LPTIM_GetCounterValue(void);
void     HAL_LPTIM_Encoder_Config(LPTIM_EncConfigTypeDef *InitStruct);
void     HAL_LPTIM_Trig_Config(LPTIM_TrigConfigTypeDef *InitStruct);
void     HAL_LPTIM_SetReloadValue(uint16_t ArrValue);
void     HAL_LPTIM_SetCompareValue(uint16_t CmpValue);
uint16_t HAL_LPTIM_GetCompareValue(void);
void     HAL_LPTIM_WaveForm_Config(LPTIM_WavePolarityTypeDef WavePolarity, LPTIM_WaveTypeDef WaveType);
void     HAL_LPTIM_Channelx_Config(LPTIM_Ch1EdgeTypeDef ChEdge, LPTIM_CHxFilterTypeDef FltClk);


#ifdef __cplusplus
}
#endif

#endif /* __SYM32L010_HAL_LPTIM_H */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
